

#include "portab.h"


/*************************************************************************/
/* Extend und Pointerroutinen */

long get_long( unsigned char **ptr )
{
	long i;

	/* auch noch nach intel wandeln! */
	i = ( (long)( *( *ptr )++ ) )<<24;
	i |= ( (long)( *( *ptr )++ ) )<<16;
	i |= ( (long)( *( *ptr )++ ) )<<8;
	i |= ( (long)( *( *ptr )++ ) );
	return ( i ) ;
}


long get_24bit( unsigned char **ptr )
{
	long i;
	i = ( (long)( *( *ptr )++ ) )<<16;
	i |= ( (long)( *( *ptr )++ ) )<<8;
	i |= ( (long)( *( *ptr )++ ) );
	return ( i );
}


long get_word( unsigned char **ptr )
{
	long i;
	i = ( (long)( *( *ptr )++ ) )<<8;
	i |= ( (long)( *( *ptr )++ ) );
	return ( i );
}


long get_byte( unsigned char **ptr )
{
	return ( (long)( *( *ptr )++ ) ) ;
}


long ext_24bit( long i )
{
	if( i&0x00800000L ) {
		return ( i|0xFF000000UL );
	}
	return ( i );
}


long ext_word( long i )
{
	if( i&0x008000L ) {
		return ( i|0xFFFF0000UL );
	}
	return ( i );
}


long ext_byte( long i )
{
	if( i&0x0080L ) {
		return ( i|0xFFFFFF00UL );
	}
	return ( i );
}


/*************************************************************************/
/* Endlich Buchstaben zeichen */


VOID copy_to_bitmap( UBYTE *dest, LONG x, LONG width, LONG y, LONG w, LONG h, UBYTE *src  )
{
	/* Der erzeugte Code ist vollst�ndig optimiert; besser geht es nur noch in Assembler */
	LONG bit, xm8;
	UBYTE *sec;

	width <<= 1; /* mal zwei, da Wortweite */
	dest += ( width*y )+( x>>3 );
	x = x&7; /* x%8 */
	xm8 = 8-x;
	while( --h >= 0 ) {
		sec = dest;
		if( x == 0 ) {
			for( bit = w;  bit > 0;  bit -= 8 ) {
				*sec++ |= *src++;
			}
		}
		else {
			for( bit = w;  bit > 0; bit -= 8 ) {
				*sec++ |= (UBYTE)( ( (SWORD)( *src ) )>>(SBYTE)x );
				*sec |= ( *src++ )<<(UBYTE)xm8;
			}
		}
		dest += width;
	}
}


/* 20.12.92 */


/*************************************************************************/
/* Buchstaben auspacken */


extern UBYTE *decode_ptr;
extern LONG repeat_count;
extern SWORD dyn_f;

extern UBYTE decode_gerade;
extern UBYTE decode_bit;
extern VOID *ph;

UBYTE get_bit( void )
{
	if( decode_bit <= 1 ) {
		decode_bit = 0x80;
		return ( *( ++decode_ptr ) & 0x80 );
	}
	else {
		decode_bit >>= 1;
		return ( *decode_ptr & decode_bit );
	}
}


LONG get_nib( void )
{
	decode_gerade = !decode_gerade;
	if( decode_gerade ) {
		return ( *( ++decode_ptr )>>4 );
	}
	else {
		return ( *decode_ptr & 0xF );
	}
}


void WriteLN( VOID*, UBYTE* );
LONG pk_packed_number( void );


LONG pk_packed_number( void )
{
	LONG i, j;

	i = get_nib();
	if( i == 0 ) {
		do {
			j = get_nib();
			i++;
		} while( j == 0 );
		for(  ;  i > 0;  i-- ) {
			j = j*16 + get_nib();
		}
		return ( j-15 + ( 13-dyn_f )*16 + dyn_f );
	}
	else if( i <= dyn_f ) {
		return ( i );
	}
	else if( i < 14 ) {
		return ( ( i-dyn_f-1 )*16 + get_nib() + dyn_f + 1 );
	}
	else {
		if( repeat_count != 0 ) {
			WriteLN( ph, "Extra Repeat-Count!" );
		}
		if( i == 14 ) {
			repeat_count = pk_packed_number();
		}
		else {
			repeat_count = 1;
		}
		return ( pk_packed_number() );
	}
}


